<template>
  <div class="app-container">
    <el-form ref="scoreForm" inline :model="scoreForm" :rules="rules">
      <el-row class="card" type="flex" justify="space-between">
        <el-button icon="el-icon-arrow-left" @click="back">返回</el-button>
        <el-button type="success" @click="goQuestion">试题录入</el-button>
      </el-row>
      <div class="card">
        <el-form-item label="试卷名称" prop="name">
          <el-input
            v-model="scoreForm.name"
            :disabled="scoreForm.status == 2"
          />
        </el-form-item>

        <el-row v-if="scoreForm.status != 2">
          <el-button type="primary" plain @click="chooseQuestion">
            试题选择
          </el-button>
        </el-row>

        <div v-for="(itemData, index) in questionArr" :key="index" class="item">
          <el-row type="flex" justify="space-between" class="item-title">
            <span>{{ questionTypeList[index] }}</span>
            <el-link
              v-if="scoreForm.status != 2 && itemData.length > 0"
              type="primary"
              :underline="false"
              @click="openPrompt(index)"
            >
              修改初始分数
            </el-link>
          </el-row>
          <el-table size="small" border highlight-current-row :data="itemData">
            <el-table-column
              type="index"
              label="序号"
              align="center"
              width="55"
            />
            <el-table-column
              label="试题内容"
              prop="titleContent"
              show-overflow-tooltip
            />
            <el-table-column label="分数" align="center" width="170">
              <template slot-scope="{ row }">
                <span v-if="scoreForm.status == 2">{{ row.score }}</span>
                <el-input-number
                  v-else
                  v-model="row.score"
                  size="mini"
                  :min="1"
                  :max="100"
                  @change="(e) => changeScore(e, row)"
                />
              </template>
            </el-table-column>
            <el-table-column
              v-if="scoreForm.status != 2"
              label="操作"
              align="center"
              width="70"
            >
              <template slot-scope="scope">
                <el-button type="text" @click="remove(scope)">移除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>

      <div v-if="statistics.length > 0" class="card">
        <el-row class="statistics-title" type="flex" justify="space-between">
          <span>分数分布</span>
          <span>
            分数总计：<i class="highlight">{{ sum }}</i> 分
          </span>
        </el-row>
        <el-row class="statistics-list" :gutter="10">
          <el-col
            v-for="item in statistics"
            :key="item.questionType"
            class="statistics-item"
            :span="12"
          >
            <el-row type="flex">
              <span>
                题型：<i class="highlight">{{ item.questionType }}</i>
              </span>
              <span>数量：{{ item.count }}</span>
              <span>
                总分值：<i class="highlight">{{ item.score }}</i> 分
              </span>
            </el-row>
          </el-col>
        </el-row>
        <el-divider />

        <el-form-item label="是否限时">
          <el-switch
            v-model="scoreForm.isTimeLimit"
            :disabled="scoreForm.status == 2"
            @change="changeSwitch"
          />
        </el-form-item>
        <el-form-item
          label="限时时长"
          prop="suggestTime"
          :rules="[
            {
              required: scoreForm.isTimeLimit,
              message: '限时时长必填',
              trigger: 'blur',
            },
          ]"
        >
          <el-input-number
            v-model="scoreForm.suggestTime"
            placeholder="分钟"
            :min="0"
            :max="720"
            :disabled="!scoreForm.isTimeLimit || scoreForm.status == 2"
          />
        </el-form-item>
        <el-form-item label="被考核人员" prop="uids">
          <el-cascader
            v-model="scoreForm.uids"
            style="width: 300px"
            clearable
            :collapse-tags="scoreForm.status != 2"
            :disabled="scoreForm.status == 2"
            :options="cascaderData"
            :props="cascaderProps"
          />
        </el-form-item>
        <el-form-item label="计分规则">
          <el-select v-model="scoreForm.rule" :disabled="scoreForm.status == 2">
            <el-option label="多选题漏选得一半分" :value="1" />
            <el-option label="多选题漏选不得分" :value="2" />
          </el-select>
        </el-form-item>

        <el-row v-if="scoreForm.status != 2" type="flex" justify="center">
          <el-button type="primary" @click="save">保存</el-button>
        </el-row>
      </div>
    </el-form>

    <el-dialog
      width="900px"
      :visible.sync="visible"
      :close-on-click-modal="false"
      :show-close="false"
    >
      <el-form inline size="small" :model="formInline">
        <el-form-item label="试题内容">
          <el-input
            v-model="formInline.titleContent"
            clearable
            placeholder="请输入试题内容"
          />
        </el-form-item>
        <el-form-item label="题型">
          <el-select
            v-model="formInline.questionType"
            clearable
            placeholder="选择题型"
          >
            <el-option label="全部" value="" />
            <el-option
              v-for="(item, index) in questionTypeList"
              :key="item"
              :label="item"
              :value="index + 1"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="分类">
          <el-cascader
            v-model="formInline.kindId"
            clearable
            :options="treeData"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="search">搜索</el-button>
        </el-form-item>
      </el-form>

      <el-table
        ref="multipleTable"
        v-loading="listLoading"
        size="small"
        border
        highlight-current-row
        :data="tableData"
        row-key="id"
        @select="handleSelect"
        @select-all="handleSelectAll"
      >
        <el-table-column type="selection" align="center" width="55" />
        <el-table-column
          label="试题内容"
          prop="titleContent"
          show-overflow-tooltip
        />
        <el-table-column
          label="题型"
          align="center"
          prop="questionTypeName"
          width="80"
        />
        <el-table-column label="分类" align="center" width="200">
          <template slot-scope="{ row }">
            <span>
              {{ row.questionKindParentName + "/" + row.questionKindName }}
            </span>
          </template>
        </el-table-column>
      </el-table>

      <div style="padding: 10px" />
      <el-pagination
        layout="total, sizes, prev, pager, next, jumper"
        :page-sizes="[10, 20, 50]"
        :current-page="pageNum"
        :page-size="pageSize"
        :total="total"
        @size-change="onPageSizeChange"
        @current-change="onCurrentPageChange"
      />

      <el-row class="dialog-footer" type="flex" justify="center">
        <el-button @click="visible = false">关 闭</el-button>
        <el-button
          type="primary"
          :disabled="selectionArr.length == 0"
          @click="submit"
        >
          提 交
        </el-button>
      </el-row>
    </el-dialog>
  </div>
</template>

<script>
import { treeSelect, getQuestionPage } from "@/api2/question";
import {
  getExamPaperInfo,
  getDjtUserList,
  addOrEditExamPaper,
} from "@/api2/examPaper";

export default {
  props: {
    examPaperId: {
      type: [String, Number],
      default: "",
    },
  },
  data() {
    return {
      questionTypeList: ["单选题", "多选题", "判断题", "填空题", "简答题"],
      questionArr: [[], [], [], [], []],
      scoreForm: {
        rule: 1,
      },
      rules: {
        name: [{ required: true, message: "试卷名称必填", trigger: "blur" }],
        uids: [
          { required: true, message: "被考核人员必填", trigger: "change" },
        ],
      },
      cascaderData: [],
      cascaderProps: {
        isTimeLimit: false,
        multiple: true,
      },
      visible: false,
      formInline: {},
      treeData: [],
      selectionArr: [],
      tableData: [],
      listLoading: false,
      pageNum: 1,
      pageSize: 10,
      total: 0,
    };
  },
  computed: {
    statistics() {
      const arr = this.questionArr.map((item, index) => {
        const score = item.reduce((s, n) => {
          return s + n.score;
        }, 0);
        return {
          questionType: this.questionTypeList[index],
          count: item.length,
          score,
        };
      });
      return arr;
    },
    sum() {
      const sum =
        this.statistics?.reduce((s, n) => {
          return s + n.score;
        }, 0) || 0;
      return sum;
    },
  },
  async mounted() {
    await this.getCascaderOption();
    this.examPaperId && this.getDetail();
  },
  methods: {
    back() {
      this.$emit("change", { componentName: "examPaperList" });
    },
    goQuestion() {
      this.$router.push("/partyManage/questionBank");
    },
    async getDetail() {
      const { data } = await getExamPaperInfo({ id: this.examPaperId });
      const uids = data.djUserList.map((item) => {
        return [item.djDeptId, item.uid];
      });
      this.scoreForm = {
        id: data.id,
        frameTextContentId: data.frameTextContentId,
        name: data.name,
        status: data.status,
        isTimeLimit: data.isTimeLimit === 2,
        suggestTime: data.suggestTime || undefined,
        uids,
        rule: data.rule,
      };
      data.djQuestionList.forEach((item) => {
        item.score = item.questionScore;
        this.questionArr[item.questionType - 1].push({ ...item });
      });
    },
    openPrompt(index) {
      this.$prompt("请输入初始分数", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        closeOnClickModal: false,
        inputValue: index === 4 ? 10 : 2,
        inputValidator: (value) => {
          if (!value) {
            return "输入不能为空";
          }
          if (isNaN(value)) {
            return "只能输入0~100之间的数字";
          }
          if (value > 100 || value < 0) {
            return "范围必须在0~100之间";
          }
        },
      })
        .then(({ value }) => {
          this.questionArr[index].forEach((item) => {
            this.$set(item, "score", value);
          });
          const typename = this.questionTypeList[index];
          this.$message.success(typename + "的初试分数设置成功！");
        })
        .catch(() => {});
    },
    chooseQuestion() {
      this.visible = true;
      this.formInline = {};
      this.selectionArr = [].concat(...this.questionArr);
      Promise.all([this.getTreeData(), this.getList()]);
    },
    async getTreeData() {
      const res = await treeSelect();
      this.treeData = res.data
        .map((item) => {
          const children = [];
          if (item.children?.length > 0) {
            item.children.forEach((v) => {
              children.push({ label: v.name, value: v.kindId });
            });
            return {
              label: item.name,
              value: item.kindId,
              children,
            };
          }
        })
        .filter(Boolean);
    },
    getList() {
      this.listLoading = true;
      const { kindId, ...formInline } = this.formInline;
      const params = {
        ...formInline,
        status: 2,
        pageNum: this.pageNum,
        pageSize: this.pageSize,
      };
      if (Array.isArray(kindId)) {
        params.kindId = kindId[kindId.length - 1];
      }
      getQuestionPage(params).then((data) => {
        this.listLoading = false;
        this.tableData = data.data;
        this.total = data.total;
        const ids = this.selectionArr.map((item) => item.id);
        this.$nextTick(() => {
          this.tableData.forEach((item, index) => {
            if (ids.some((v) => v == item.id)) {
              this.$refs.multipleTable.toggleRowSelection(
                this.$refs.multipleTable.data[index],
                true
              );
            }
          });
        });
      });
    },
    onPageSizeChange(val) {
      this.pageSize = val;
      this.pageNum = 1;
      this.getList();
    },
    onCurrentPageChange(val) {
      this.pageNum = val;
      this.getList();
    },
    search() {
      this.pageNum = 1;
      this.getList();
    },
    handleSelect(selection, row) {
      if (this.selectionArr.find((item) => item.id === row.id)) {
        this.selectionArr = this.selectionArr.filter((item) => {
          return item.id != row.id;
        });
      } else {
        this.selectionArr.push(row);
      }
    },
    handleSelectAll(rows) {
      if (rows.length > 0) {
        this.selectionArr = [...rows];
      } else {
        this.tableData.forEach((row) => {
          this.selectionArr = this.selectionArr.filter((item) => {
            return item.id != row.id;
          });
        });
      }
    },
    submit() {
      const arr = [[], [], [], [], []];
      this.selectionArr.forEach((item) => {
        this.$set(item, "score", item.questionType === 5 ? 10 : 2);
        arr[item.questionType - 1].push({ ...item });
      });
      this.questionArr = arr;
      this.visible = false;
    },
    changeScore(val, row) {
      this.$set(row, "score", val);
    },
    remove({ row, $index }) {
      this.questionArr[row.questionType - 1].splice($index, 1);
    },
    changeSwitch(val) {
      this.scoreForm.suggestTime = !val ? undefined : 60;
    },
    async getCascaderOption() {
      const res = await getDjtUserList();
      const obj = {};
      res.data.forEach((item) => {
        const { djDeptName: label, djDeptId: value, userName, uid } = item;
        if (!obj[label]) {
          obj[label] = {
            label,
            value,
            children: [],
          };
        }
        obj[label].children.push({
          label: userName,
          value: uid,
        });
      });
      this.cascaderData = Object.values(obj);
    },
    save() {
      const isLen = this.questionArr.some((item) => {
        return item.length > 0;
      });
      if (!isLen) {
        this.$message.error("至少选择一道试题！");
        return;
      }
      this.$refs.scoreForm.validate(async (valid) => {
        if (valid) {
          const titleItems = this.questionArr.map((item, index) => {
            const questionEntityList = item?.map((v) => {
              const { id, score } = v;
              return { id, score };
            });
            return {
              name: this.questionTypeList[index],
              questionEntityList,
            };
          });
          const isMarking = titleItems.some(
            (item) =>
              ["填空题", "简答题"].includes(item.name) &&
              item.questionEntityList.length > 0
          );
          let { uids, isTimeLimit, ...form } = this.scoreForm;
          uids = uids.map((item) => item[1]);
          isTimeLimit = isTimeLimit ? 2 : 1;

          const params = { titleItems, isMarking, uids, isTimeLimit, ...form };
          await addOrEditExamPaper(params);
          const tips = form.id ? "修改" : "新建";
          this.$message.success("试卷" + tips + "成功");
          this.back();
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.app-container {
  min-height: 100%;
  background-color: #f4f5fc;
  .card {
    padding: 15px 20px;
    border: 1px solid #dcdfe6;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
    background-color: #fff;
    & + .card {
      margin-top: 10px;
    }
  }
}
.item {
  margin: 22px 0;
  &:last-child {
    margin-bottom: 0;
  }
  &-title {
    font-size: 16px;
    margin-bottom: 10px;
    span {
      &:first-child {
        padding-left: 10px;
        position: relative;
        color: #364a71;
        &::before {
          content: "";
          position: absolute;
          left: 0;
          width: 3px;
          height: 100%;
          background-color: #e86565;
        }
      }
    }
  }
}
.statistics-title {
  font-size: 14px;
  margin-bottom: 12px;
  span:first-child {
    color: #364a71;
  }
}
.highlight {
  color: #3b95ff;
  font-style: inherit;
}
.statistics-item {
  margin-top: 10px;
  > div {
    font-size: 14px;
    padding: 10px 20px;
    color: #333;
    background-color: #e7f2ff;
    span {
      &:first-child {
        width: 35%;
      }
      &:nth-child(2) {
        width: 30%;
      }
      &:nth-child(-n + 2) {
        margin-right: 10px;
      }
    }
  }
  &:nth-child(-n + 2) {
    margin-top: 0;
  }
}
.dialog-footer {
  margin-top: 20px;
}
.el-divider--horizontal {
  margin: 18px 0;
}
</style>
